package tom.spring.cloud.gateway;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.standard.TemporalAccessorParser;
import org.springframework.format.datetime.standard.TemporalAccessorPrinter;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.config.WebFluxConfigurationSupport;
import org.springframework.web.reactive.config.WebFluxConfigurer;

import java.lang.annotation.Annotation;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 基于配置的gateway
 * http://localhost:8090/actuator/gateway/routes
 * 屏蔽spring-security
 * @author ZHUFEIFEI
 */
@Slf4j
@EnableWebFlux
@EnableDiscoveryClient
@SpringBootApplication
@ComponentScan(
        excludeFilters = {
                //正则过滤掉符合条件的类
                @ComponentScan.Filter(type = FilterType.REGEX,
                        pattern = "tom\\.spring\\.cloud\\.gateway\\..*"
                )
        })
public class Gateway05Application {

    public static void main(String[] args) {
        SpringApplication.run(Gateway05Application.class, args);
    }


    @Configuration
    @EnableConfigurationProperties(WebFluxProperties.class)
    class MyWebFluxConfigurer implements WebFluxConfigurer {

        @Autowired
        private WebFluxProperties webFluxProperties;

        @Override
        public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
            //打印header详情
            configurer.defaultCodecs().enableLoggingRequestDetails(true);
        }

        /**
         * {@link WebFluxConfigurationSupport#webFluxConversionService()}
         * {@link org.springframework.boot.context.properties.bind.BindConverter.CompositeConversionService#convert(Object, TypeDescriptor, TypeDescriptor)}
         * @param registry
         */
        @Override
        public void addFormatters(FormatterRegistry registry) {
            if (StringUtils.isNotBlank(webFluxProperties.getDateFormat())) {
                //自定义format
                DateTimeFormatter dtf = DateTimeFormatter.ofPattern(webFluxProperties.getDateFormat());
                registry.addFormatterForFieldType(ZonedDateTime.class
                        ,new TemporalAccessorPrinter(dtf), new TemporalAccessorParser(ZonedDateTime.class, dtf));
                log.info("add DateTimeFormatter : {} for pattern {}", dtf.getResolverStyle(), webFluxProperties.getDateFormat());
            }
        }
    }

    @EnableWebFluxSecurity
    class MyFluxSecurityConfig {

        @Bean
        public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
            //允许所有请求
            return http.authorizeExchange().anyExchange().permitAll().and().build();
        }

    }
}
